// 2025/3/16
// https://leetcode.cn/problems/path-sum-iii/description/?envType=study-plan-v2&envId=top-100-liked
// 路径总合

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
    public:
        int rootSum(TreeNode* root, long long targetSum)
        {
            if(root == nullptr) return 0;
    
            int ret = root->val == targetSum ? 1 : 0;
            ret += rootSum(root->left, targetSum - root->val);
            ret += rootSum(root->right, targetSum - root->val);
            return ret;
        }
    
        int pathSum(TreeNode* root, int targetSum) {
            if(root == nullptr) return 0;
    
            int ans = rootSum(root, targetSum);
            ans += pathSum(root->left, targetSum);
            ans += pathSum(root->right, targetSum);
            return ans;
        }
    };

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
    public:
        unordered_map<long long, int> pre;
    
        int dfs(TreeNode* root, long long cur, int targetSum)
        {
            if(root == nullptr) return 0;
    
            int ret = 0;
            cur += root->val;
            if(pre.count(cur - targetSum))
                ret = pre[cur - targetSum];
    
            ++pre[cur];
            ret += dfs(root->left, cur, targetSum);
            ret += dfs(root->right, cur, targetSum);
            --pre[cur];
    
            return ret;
        }
    
        int pathSum(TreeNode* root, int targetSum) {
            if(root == nullptr) return 0;
    
            pre[0] = 1;
            return dfs(root, 0, targetSum);
        }
    };